openUBMC支持OEE构建特性设计说明书

所属SIG组:CICD SIG
落入版本:openUBMC 26.3.0
设计人员:yangzhun
日期:2026-04-18

Copyright © 2025 openUBMC Community

您对"本文档"的复制,使用,使用,修改及分发受木兰宽松许可证, 第2版协议(以下简称"MulanPSL2")的约束。 为了方便用户理解,您可以通过访问https://license.coscl.org.cn/MulanPSL2了解MulanPSL2的概要 (但不是替代)。 MulanPSL2的完整协议内容您可以访问如下网址获取:https://license.coscl.org.cn/MulanPSL2

改版记录

日期修订版本修订描述作者审核
2026-04-18V1.1bingo 支持 oee 构建yangzhun
2026-04-10V1.0初始版本,支持OEE工具安装和组件构建yangzhun

目录

[TOC]

1.特性概述

1.1目的

本特性主要解决bingo构建系统支持OEE(OpenEuler Embedded)构建模式,包括:

  • OEE开发环境初始化和工具链安装
  • 基于OEE工具链的组件编译和发布
  • OEE产品固件包(GPP)构建
  • OEE Rootfs镜像构建

通过配置驱动+继承架构的设计,实现OEE构建完整支持,同时保持与现有RTOS构建模式的完全兼容。

1.2范围

本特性涵盖以下核心功能:

表1:特性场景相关性分析

场景编号编号1编号2编号3编号4编号5编号6
场景名称OEE开发环境初始化OEE工具链安装基于OEE工具链编译组件OEE GPP固件构建OEE Rootfs镜像构建构建OEE产品包
特性是否相关

核心实现:

  • 配置层:rtos_version="oee"触发OEE模式,tools_install配置工具安装
  • 安装层:CustomInstaller基类+子类实现多模式安装
  • 构建层:Base/Oee继承架构+工厂模式,区分RTOS/OEE构建流程

1.3特性需求列表

表2:特性需求列表

需求名称特性描述实现模块
支持OEE构建模式rtos_version="oee"触发OEE构建流程config.py
支持OEE工具链安装CustomInstaller支持local/oee/custom/default四种模式task_custom_installer.py
支持OEE GPP构建OeeBuildGppBin子类实现OEE固件打包task_buildgppbin.py
支持OEE Rootfs构建OeeBuildRootfsImg子类实现OEE镜像构建task_build_rootfs_img.py
向后兼容RTOS构建流程不受影响,工厂默认选择父类所有模块

2.需求场景分析

2.1特性需求来源与价值概述

需求来源

openUBMC bingo构建系统当前仅支持RTOS构建模式(1711/1712芯片),需要扩展支持OpenEuler Embedded(OEE)构建模式。OEE基于Linux系统,其构建流程与RTOS存在显著差异:

维度RTOS模式OEE模式
Boot加载Hi1711_boot / LiteOS_MU-Boot SPL + U-Boot
内核类型RTOS内核Linux内核(fitImage)
Rootfs来源rtos.tar.gz解压squashfs镜像解压
签名机制签名uboot和ko模块不签名
工具链RTOS SDK固定安装可配置自定义安装

价值概述

  • 降低开发门槛:开发者无需手动配置复杂的OEE环境
  • 提高构建灵活性:支持多种工具链安装模式
  • 促进生态融合:使openUBMC能够无缝集成OEE生态
  • 架构清晰:继承+工厂模式职责分明,易于扩展

2.2特性场景分析

场景描述

通过platform/options/rtos_versiontools_install两个配置协同工作:

配置联动关系

manifest.yml

    ├─ platform.options.rtos_version="oee"
    │       │
    │       ▼
    │   config.chip = "oee"(config.py解析)
    │       │
    │       ├─ 触发OEE构建流程(task_buildgppbin/task_build_rootfs_img)
    │       ├─ 工厂函数选择OEE子类(create_xxx_builder)
    │       └─ 跳过RTOS特有options(task_build_conan)

    └─ tools_install
        ├─ build_tool → CustomBuildToolsInstaller(task_download_buildtools)
        └─ sdk_tool → CustomSDKInstaller(task_download_dependency)

场景1:OEE本地模式构建

  • 配置:rtos_version="oee", tools_install/build_tool.label="local"
  • 流程:使用本地OEE工具链,跳过下载,直接构建OEE固件包

场景2:OEE下载模式构建

  • 配置:rtos_version="oee", tools_install/build_tool.label="oee"
  • 流程:下载并安装OEE工具链,构建OEE固件包

场景3:RTOS默认模式构建

  • 配置:rtos_version="rtos_v2"
  • 流程:使用原有RTOS流程,完全向后兼容

2.3特性影响分析

平台差异性分析

  • 操作系统:支持Linux系统(Ubuntu 24.04)
  • 硬件平台
    • OEE模式:x86_64开发主机,编译armv7a目标平台
    • RTOS模式:1711/1712芯片平台
  • 兼容性:通过rtos_version和chip字段实现向后兼容

特性冲突分析

无重大特性冲突,通过继承架构和工厂模式实现隔离:

  • 构建模式隔离:chip类型决定构建流程,父类/子类分离
  • 安装模式隔离:label字段决定安装方式,default使用原有流程

3.特性/功能实现原理

3.1目标

实现OEE构建完整支持,核心目标:

  1. 配置驱动:rtos_version="oee"和tools_install配置触发OEE模式
  2. 继承架构:Base/Oee子类区分RTOS/OEE构建流程
  3. 向后兼容:RTOS产品构建流程不受影响
  4. 易于扩展:支持后续添加其他芯片类型和安装模式

3.2总体方案

架构设计

采用父类-子类-工厂三层架构:

┌─────────────────────────────────────────────────────────┐
│                    TaskClass(入口)                      │
│  ┌─────────────────────────────────────────────────┐    │
│  │              工厂函数 create_xxx_builder           │    │
│  │         根据 config.chip 选择实例化类               │    │
│  └─────────────────────────────────────────────────┘    │
│                           │                              │
│           ┌───────────────┴───────────────┐              │
│           ▼                               ▼              │
│  ┌─────────────────┐           ┌─────────────────┐      │
│  │ BaseBuildXxx    │           │ OeeBuildXxx     │      │
│  │   (RTOS)        │◄──────────│   (OEE)         │      │
│  └─────────────────┘           └─────────────────┘      │
│                                                           │
│  - 原有RTOS逻辑不变               - 重写OEE特有方法       │
│  - 通用方法供复用                 - 跳过RTOS特有逻辑      │
└─────────────────────────────────────────────────────────┘

配置解析流程

图1:配置解析与构建模式选择流程

manifest.yml配置
├─ platform/options/rtos_version: "oee"
│   ├─ "oee": OEE构建模式
│   ├─ "rtos_v2_1712": 1712芯片RTOS模式
│   └─ "rtos_v2": 1711芯片RTOS模式(默认)

└─ tools_install(可选)
    ├─ build_tool: 编译器工具链配置
    │   ├─ label: local/oee/custom/default
    │   ├─ work_path: 工作路径
    │   └─ install.mode: oee/default/custom
    └─ sdk_tool: SDK依赖配置

↓ config.py解析(merge_platform_package)

rtos_version → config.chip类型判断
├─ rtos_version="oee" → chip="oee"
├─ rtos_version="rtos_v2_1712" → chip="1712"
└─ rtos_version="rtos_v2"或不配置 → chip="1711"

↓ 构建流程判断

chip="oee"
├─ task_build_conan.py: 跳过RTOS options
├─ task_oct_rtos.py: 直接return,跳过RTOS裁剪
├─ task_buildgppbin.py: create_gpp_builder() → OeeBuildGppBin
└─ task_build_rootfs_img.py: create_rootfs_builder() → OeeBuildRootfsImg

chip="1711"/"1712"
├─ task_build_conan.py: 执行RTOS options
├─ task_oct_rtos.py: 执行RTOS裁剪流程
├─ task_buildgppbin.py: create_gpp_builder() → BaseBuildGppBin
└─ task_build_rootfs_img.py: create_rootfs_builder() → BaseBuildRootfsImg

对接原则

  1. 配置驱动原则:rtos_version决定构建模式,tools_install决定安装方式
  2. 向后兼容原则:rtos_version配置RTOS版本时,使用原有流程,tools_install不配置,使用原有流程
  3. 可扩展原则:通过子类继承支持不同芯片类型
  4. 工厂模式原则:通过工厂函数统一选择构建器

4.Use Case一实现:OEE工具链安装

4.1设计思路

通过manifest.yml配置声明OEE工具链安装需求,CustomInstaller基类提供通用安装框架,子类实现特化安装逻辑。

核心设计点

  1. 配置验证:validate_config()确保配置完整性和安全性
  2. 路径安全:sanitize_path()限制操作路径在安全范围内
  3. 下载机制:download_files()支持wget下载和sha256sum验证
  4. 安装逻辑:execute_specified_install()执行OEE安装脚本
  5. 缓存验证:verify_install_cache()避免重复安装

4.2约束条件

前提条件

  • manifest.yml中配置platform/options/rtos_version="oee"
  • tools_install配置完整且格式正确

限制条件

  • oee模式需要网络连接和wget工具
  • 安装路径需足够磁盘空间(至少2GB)

4.3详细实现

CustomInstaller基类设计(task_custom_installer.py)

核心属性

属性名称类型说明
tool_typestr工具类型标识(build_tool/sdk_tool)
config_keystr配置键(tools_install/{tool_type})
install_configdict安装配置字典
install_flag_filestr安装标志文件路径
download_cache_filestr下载缓存文件路径

核心方法设计

方法名称功能描述关键实现
validate_config()验证配置完整性递归检查字段类型、必需性、格式合法性
sanitize_path()路径安全检查白名单检查,限制在/opt、/home、/tmp等安全目录
calculate_file_hash()计算文件哈希使用hashlib.sha256分块计算(8KB)
calculate_directory_hash()计算目录哈希遍历文件,计算相对路径哈希
download_files()下载文件wget下载,sha256sum验证,缓存管理
install_downloaded_files()安装文件根据mode选择安装方式(default/oee/custom)
verify_install_cache()验证缓存比对文件哈希,判断缓存有效性
generate_install_flag()生成标志文件JSON格式记录安装状态和文件哈希
cleanup_on_failure()失败清理删除工作目录,清理临时文件
run()主执行流程配置验证→缓存检查→下载→安装→生成标志

配置验证设计(validate_config)

验证规则

  1. 必需字段验证:work_path必须存在且非空
  2. 类型验证:download必须为列表,install必须为字典
  3. 格式验证:sha256sum必须为64位十六进制字符串
  4. 逻辑验证:label为local时download可选,mode为custom时cmds必须存在

代码实现(task_custom_installer.py:43-82):

python
def validate_config(self, config):
    if not isinstance(config, dict):
        raise errors.BmcGoException(f"{self.config_key}配置必须是字典类型")
    
    if 'work_path' not in config:
        raise errors.BmcGoException(f"{self.config_key}缺少必需字段: work_path")
    
    # download字段验证
    if label != 'local' and 'download' in config:
        if not isinstance(config['download'], list) or len(config['download']) == 0:
            raise errors.BmcGoException(f"{self.config_key}.download必须是非空列表")
        for i, item in enumerate(config['download']):
            if 'sha256sum' in item:
                if not isinstance(sha256sum, str) or len(sha256sum) != 64:
                    raise errors.BmcGoException(f"sha256sum必须是64位的SHA256哈希值")
    
    # install.mode验证
    if mode not in ['default', 'oee', 'custom']:
        raise errors.BmcGoException(f"install.mode必须是default、oee或custom")

安装模式详解

label字段决定下载行为

label下载说明
local不下载使用work_path本地文件
oee下载执行download配置,调用子类execute_specified_install
custom下载执行download配置,执行install.cmds命令序列
default下载使用默认安装方案

install.mode字段决定安装执行

mode执行方式代码位置
default复制shutil.copytree(work_path, install.path)
oee子类方法execute_specified_install()(子类重写)
custom命令序列执行install.cmds中的命令

CustomBuildToolsInstaller子类设计

特化方法(task_custom_installer.py末尾):

python
class CustomBuildToolsInstaller(CustomInstaller):
    """构建工具安装器"""
    
    def __init__(self, config, work_name=""):
        super(CustomBuildToolsInstaller, self).__init__(config, "build_tool", work_name)
    
    def execute_specified_install(self, install_path):
        """执行OEE安装逻辑"""
        work_path = self.install_config.get('work_path')
        os.chdir(work_path)
        
        # 清除LD_LIBRARY_PATH避免库冲突
        if 'LD_LIBRARY_PATH' in os.environ:
            del os.environ['LD_LIBRARY_PATH']
        
        # 执行OEE工具链安装脚本
        install_script = "openeuler-x86_64-obmc-armv7a-ast2600-toolchain-24.03-LTS.sh"
        self.run_command(f"sh {install_script} -d {install_path} -y")

task_download_buildtools.py集成

代码实现(task_download_buildtools.py):

python
class TaskClass(Task):
    def __init__(self, config, work_name=""):
        super(TaskClass, self).__init__(config, work_name)
        self.download_buildtools = DownloadDefaultBuildtools(config)
        self.custom_installer = CustomBuildToolsInstaller(config)
        self.use_custom_install = False
    
    def check_custom_install_config(self):
        """检查tools_install配置"""
        config = self.get_manufacture_config("tools_install/build_tool")
        if not config:
            return False
        label = config.get('label', 'default')
        return label != 'default'
    
    def run(self):
        if self.check_custom_install_config():
            self.custom_installer.run()  # 自定义安装
            self.use_custom_install = True
        else:
            self.download_buildtools.run()  # 默认安装
    
    def install(self):
        if self.use_custom_install:
            return  # 自定义安装已完成
        else:
            self.download_buildtools.install()

4.4子系统间接口

manifest.yml配置接口

新增配置字段

yaml
# 构建模式配置(关键)
platform:
  conan: "ibmc_sdk/5.13.00.01.b002@openubmc/stable"
  options:
    rtos_version: "oee"  # OEE构建模式

# 工具安装配置(可选)
tools_install:
  build_tool:
    label: "local"
    work_path: "/root/oee_compiler"
    verify: true
    download:  # label非local时使用
      - url: "https://repo/sdk.tar.gz"
        sha256sum: "abc123..."
    install:
      mode: "oee"
      path: "/opt/oee_sdk"

JSON Schema接口

manifest.schema.json新增tools_install schema定义,包括:

  • tool_install类型定义
  • label枚举限制(local/oee/custom/default)
  • download数组验证
  • install.mode验证

4.5子系统详细设计

主执行流程(run方法)

python
def run(self):
    """主执行函数"""
    try:
        # 1. 获取配置
        install_config = self.get_manufacture_config(self.config_key)
        if not install_config or install_config.get('label') == 'default':
            return  # 使用默认安装
        
        # 2. 验证配置
        self.validate_config(install_config)
        self.install_config = install_config
        
        # 3. 缓存验证
        if self.verify_install_cache():
            return  # 缓存有效,跳过安装
        
        # 4. 下载文件
        self.download_files()
        
        # 5. 安装文件
        self.install_downloaded_files()
        
        # 6. 生成安装标志
        self.generate_install_flag(success=True)
        
    except Exception as e:
        self.cleanup_on_failure()
        self.generate_install_flag(success=False, error_msg=str(e))
        raise errors.BmcGoException(f"安装失败: {str(e)}")

安装缓存验证机制

缓存验证流程

python
def verify_install_cache(self):
    """验证安装缓存是否有效"""
    # 1. 检查verify配置
    if not self.install_config.get('verify', False):
        return False
    
    # 2. 加载标志文件
    flag_data = self.load_install_flag()
    if not flag_data or not flag_data.get('success'):
        return False
    
    # 3. 计算当前文件哈希
    work_path = self.install_config.get('work_path')
    current_hash = self.calculate_directory_hash(work_path)
    
    # 4. 比对哈希值
    files_hash = flag_data.get('files_hash', {})
    for rel_path, expected_hash in files_hash.items():
        if current_hash.get(rel_path) != expected_hash:
            return False  # 文件变化,缓存失效
    
    return True  # 缓存有效

4.6DFX属性设计

性能设计

性能目标

  • 下载性能:10MB/s以上网络下载速度
  • 验证性能:100MB文件哈希验证时间小于10秒
  • 安装性能:工具链安装时间小于5分钟

性能优化措施

  • 下载缓存:已下载文件不重复下载
  • 安装缓存:已安装工具链不重复安装(verify=true)
  • 分块哈希:使用8KB分块计算,减少内存占用

安全设计

安全威胁分析

威胁类型风险描述消减措施实现位置
路径注入恶意配置危险路径sanitize_path()白名单检查task_custom_installer.py:84-107
文件篡改下载文件被篡改sha256sum哈希验证task_custom_installer.py:109-118
命令注入custom模式恶意命令配置验证,日志审计task_custom_installer.py:43-82
缓存篡改标志文件被篡改文件权限控制,哈希比对task_custom_installer.py:154-169

路径安全检查实现

python
def sanitize_path(self, path):
    """路径安全检查"""
    path = os.path.expanduser(path)
    path = os.path.abspath(path)
    
    # 白名单检查:只允许操作安全目录
    allowed_paths = ['/opt', '/home', '/tmp', '/var/tmp']
    
    # 添加temp_path到允许列表
    if hasattr(self.config, 'temp_path'):
        allowed_paths.append(self.config.temp_path)
    
    if not any(path.startswith(allowed) for allowed in allowed_paths):
        raise errors.BmcGoException(f"路径{path}不在允许的目录范围内")

4.7系统外部接口

manifest.yml配置接口

配置示例对比

表3:配置示例对比

构建模式rtos_versiontools_install配置构建行为
OEE本地模式"oee"label="local", work_path本地路径使用本地OEE工具链构建
OEE下载模式"oee"label="oee", download配置下载并安装OEE工具链构建
自定义模式"oee"label="custom", cmds配置按自定义流程安装并构建
RTOS默认模式"rtos_v2"不配置或label="default"使用原有RTOS流程构建
1712 RTOS模式"rtos_v2_1712"不配置或label="default"使用1712芯片RTOS流程构建

4.8自测用例设计

功能测试用例

用例1:OEE本地模式完整构建流程

测试项测试内容
前置条件本地存在OEE工具链,manifest.yml配置rtos_version="oee"
配置rtos_version="oee", label="local", work_path="/root/oee_compiler"
操作bingo build -b oee_board
验证点1. config.chip="oee"
2. CustomBuildToolsInstaller识别label="local"
3. download_files()跳过下载
4. OeeBuildGppBin构建OEE固件
5. OeeBuildRootfsImg构建OEE rootfs
结果构建成功,生成OEE产品固件包

用例2:OEE下载模式工具链安装

测试项测试内容
前置条件网络连接正常,wget可用
配置rtos_version="oee", label="oee", download URL和sha256sum
操作bingo build -b oee_board(首次构建)
验证点1. wget下载工具链压缩包
2. sha256sum验证通过
3. execute_specified_install()执行安装脚本
4. generate_install_flag()生成成功标志
结果工具链安装成功,生成install_flag.json

用例3:缓存验证测试

测试项测试内容
前置条件已完成工具链安装,install_flag.json存在
配置verify=true
操作bingo build(第二次构建)
验证点1. verify_install_cache()加载标志文件
2. 哈希比对通过
3. 跳过下载和安装流程
结果构建成功,节省构建时间

5.Use Case二实现:SDK依赖安装

SDK依赖安装与OEE工具链安装类似,主要差异:

表4:OEE工具链安装与SDK依赖安装对比

对比项OEE工具链安装SDK依赖安装
Task类CustomBuildToolsInstallerCustomSDKInstaller
配置键tools_install/build_tooltools_install/sdk_tool
集成模块task_download_buildtools.pytask_download_dependency.py
安装内容编译器工具链SDK依赖库、sysroot
安装脚本openeuler-toolchain.sh根据SDK类型选择

CustomSDKInstaller子类设计

python
class CustomSDKInstaller(CustomInstaller):
    """SDK依赖安装器"""
    
    def __init__(self, config, work_name=""):
        super(CustomSDKInstaller, self).__init__(config, "sdk_tool", work_name)
    
    def execute_specified_install(self, install_path):
        """执行SDK特化安装逻辑"""
        work_path = self.install_config.get('work_path')
        # 默认使用复制模式
        if install_path:
            shutil.copytree(work_path, install_path)

详细实现流程参考Use Case一。

6.Use Case三实现:OEE GPP构建

6.1设计思路

采用继承架构区分RTOS/OEE GPP构建流程:

  • BaseBuildGppBin:RTOS父类,保持原有逻辑不变
  • OeeBuildGppBin:OEE子类,重写OEE特有方法
  • create_gpp_builder:工厂函数,根据chip类型选择构建器

6.2类结构设计

继承架构图

BaseBuildGppBin(父类,243行)
├─ move_dependency: RTOS boot准备(Hi1711_boot/LiteOS_M)
├─ prepare_boot_1711/1712: 签名uboot
├─ build_gpp_hpm_bin: 构建RTOS GPP(hpm_top + boot + rtos_kernel + hpm_sub + rootca + cms + crl + rootfs)
├─ write_gpp_bin: 打包RTOS固件
└─ run: RTOS完整流程

OeeBuildGppBin(子类,+45行)extends BaseBuildGppBin
├─ __init__: 社区适配suffix(openubmc/iBMC)
├─ move_dependency: 复制OEE boot文件(u-boot-spl + u-boot + fitImage + rootfs)
├─ build_gpp_hpm_bin: 创建MMC boot区(mmc-bootarea.img 2MB)
├─ write_gpp_bin: 打包OEE固件(hpm_top + mmc-bootarea + kernel + rootfs.tar.gz)
└─ run: 继承父类,自动调用重写方法

工厂函数:create_gpp_builder(config) → 根据chip选择子类/父类

6.3OEE GPP构建流程

图2:OEE GPP构建流程

OeeBuildGppBin.run()

    ├─ move_dependency()(重写)
    │   ├─ cp u-boot-spl.bin → hpm_build_dir(SPL加载器)
    │   ├─ cp u-boot.bin → hpm_build_dir(主U-Boot)
    │   ├─ cp fitImage-obmc-phosphor-initramfs → kernel.bin(Linux内核+initramfs)
    │   ├─ cp rootfs_BMC.img → hpm_build_dir
    │   └─ cp rootfs_BMC.tar.gz → hpm_build_dir

    └─ build_gpp_hpm_bin()(重写)
        ├─ dd创建mmc-bootarea.img(2MB空白)
        ├─ dd写入u-boot-spl(偏移0)
        ├─ dd写入u-boot(偏移64KB)
        ├─ cp hpm_header.config(HPM配置)
        ├─ gpp_header hpm(生成HPM头)
        └─ write_gpp_bin()打包:hpm_top + mmc-bootarea + kernel + rootfs.tar.gz

6.4关键代码实现

OeeBuildGppBin类实现(task_buildgppbin.py:191-227):

python
class OeeBuildGppBin(BaseBuildGppBin):
    def __init__(self, config, work_name=""):
        super(OeeBuildGppBin, self).__init__(config, work_name=work_name)
        # 社区版本适配
        if misc.community_name() != "openubmc":
            self.suffix = "iBMC"
    
    def move_dependency(self):
        """OEE模式:移动OEE boot和内核文件"""
        self.info("OEE模式:跳过RTOS boot准备逻辑")
        self.chdir(self.config.hpm_build_dir)
        # 复制OEE boot文件
        self.run_command(f"cp -af {self.config.sdk_path}/u-boot-spl.bin ./")
        self.run_command(f"cp -af {self.config.sdk_path}/u-boot.bin ./")
        self.run_command(f"cp -af {self.config.sdk_path}/fitImage-obmc-phosphor-initramfs-evb-ast2600 ./kernel.bin")
        self.run_command(f"cp -af {self.config.work_out}/rootfs_{self.suffix}.img ./")
        self.run_command(f"cp -af {self.config.work_out}/rootfs_{self.suffix}.tar.gz ./")
    
    def build_gpp_hpm_bin(self):
        """OEE模式:构建MMC boot区"""
        self.info("OEE模式:构建OEE GPP二进制文件")
        # 创建2MB空白MMC boot区
        self.run_command(f"dd if=/dev/zero of=mmc-bootarea.img count=2 bs=1M")
        # 写入u-boot-spl(偏移0)
        self.run_command(f"dd if=u-boot-spl.bin of=mmc-bootarea.img conv=notrunc")
        # 写入u-boot(偏移64KB)
        self.run_command(f"dd if=u-boot.bin of=mmc-bootarea.img conv=notrunc seek=64 bs=1K")
        # HPM配置和头生成
        self.run_command(f"cp -af {self.config.board_path}/hpm_header.config ./")
        self.run_command("gpp_header hpm")
        self.write_gpp_bin()
    
    def write_gpp_bin(self):
        """OEE模式:打包OEE固件"""
        self.info(f"打包: {self.config.board_name}_gpp.bin")
        files = f"hpm_top_header mmc-bootarea.img kernel.bin rootfs_{self.suffix}.tar.gz"
        target_path = f"{self.config.work_out}/{self.config.board_name}_gpp.bin"
        cmd = f"cat {files}"
        self.pipe_command([cmd], target_path)

工厂函数实现(task_buildgppbin.py:230-234):

python
def create_gpp_builder(config, work_name=""):
    """工厂函数:根据chip类型选择GPP构建器"""
    if config.chip == "oee":
        return OeeBuildGppBin(config, work_name)
    else:
        return BaseBuildGppBin(config, work_name)

class TaskClass(Task):
    def __init__(self, config, work_name=""):
        super(TaskClass, self).__init__(config, work_name)
        self.gpp_builder = create_gpp_builder(config, work_name)
    
    def run(self):
        self.gpp_builder.run()

6.5GPP固件结构对比

表5:RTOS与OEE GPP固件结构对比

固件类型组成部分Boot区布局
RTOS GPPhpm_top + boot + rtos_kernel + hpm_sub + rootca + cms + crl + rootfs.tar.gzHi1711_boot(768KB)+ LiteOS_M
OEE GPPhpm_top + mmc-bootarea(2MB) + kernel.bin + rootfs.tar.gzu-boot-spl(偏移0)+ u-boot(偏移64KB)

关键差异

  • RTOS:签名uboot和ko模块,包含rootca和cms签名文件
  • OEE:不签名,使用MMC boot区(u-boot-spl + u-boot)

6.6社区版本适配

通过misc.community_name()适配命名:

python
if misc.community_name() != "openubmc":
    self.suffix = "iBMC"  # iBMC社区版本
else:
    self.suffix = "BMC"   # openUBMC社区版本

影响文件命名:

  • rootfs_{suffix}.img → rootfs_iBMC.img 或 rootfs_BMC.img
  • rootfs_{suffix}.tar.gz → rootfs_iBMC.tar.gz 或 rootfs_BMC.tar.gz

7.Use Case四实现:OEE Rootfs构建

7.1设计思路

同样采用继承架构区分RTOS/OEE Rootfs构建:

  • BaseBuildRootfsImg:RTOS父类,保持原有逻辑(977行)
  • OeeBuildRootfsImg:OEE子类,重写build_common_fs和make_rootfs_img方法(+74行)
  • create_rootfs_builder:工厂函数,根据chip类型选择构建器

7.2类结构设计

继承架构图

BaseBuildRootfsImg(父类,977行)
├─ set_evn: 解压RTOS tar.gz
├─ build_common_fs: RTOS文件系统构建(解压tar.gz + 合并组件 + strip)
├─ make_rootfs_img: RTOS镜像制作(schema_custom + mapping_patch + precompile + sign_ko + make_img)
├─ sign_ko: 签名ko模块
├─ make_img: 制作ext4镜像(调用sign_ko)
└─ run: RTOS完整流程(set_evn → build_common_fs → merge_whitelist → make_rootfs_img → post_make)

OeeBuildRootfsImg(子类,+74行)extends BaseBuildRootfsImg
├─ __init__: 社区适配rootfs_img_path
├─ build_common_fs: 解压OEE squashfs + 合并组件 + 删除.a静态库(重写)
├─ make_rootfs_img: OEE镜像制作(跳过schema_custom、mapping_patch、precompile)
├─ make_img: 继承父类,但sign_ko在OEE下跳过(不重写,但make_img不调用sign_ko)
└─ run: 继承父类,自动调用重写方法

工厂函数:create_rootfs_builder(config) → 根据chip选择子类/父类

7.3OEE Rootfs构建流程

图3:OEE Rootfs构建流程

OeeBuildRootfsImg.run()(继承父类流程)

    ├─ set_evn()(继承)

    ├─ build_common_fs()(重写)
    │   ├─ unsquashfs解压OEE镜像(obmc-phosphor-image-evb-ast2600.squashfs-xz)
    │   ├─ cp合并openubmc组件(rootfs_path → rtos_rootfs)
    │   ├─ copy_upgrade_dat_file()(继承)
    │   ├─ strip处理(继承)
    │   ├─ find删除.a静态库(OEE特有)
    │   └─ build_cfg_fs()(继承)

    ├─ merge_whitelist()(继承)

    ├─ make_rootfs_img()(重写)
    │   ├─ make_datafs_img()(继承)
    │   ├─ component_cust_conf()(继承)
    │   ├─ merge_sr_and_converge_version()(继承)
    │   ├─ create_csr_version_file()(继承)
    │   ├─ trim_mds_and_sr_json()(继承)
    │   ├─ component_swbom()(继承)
    │   ├─ cp rootfs到mnt_datafs(继承)
    │   ├─ rootfs_customization()(继承)
    │   ├─ create_global_properties_config_file()(继承)
    │   └─ make_img()(继承,但不调用sign_ko)

    └─ post_make_rootfs_img()(继承)

7.4关键代码实现

OeeBuildRootfsImg类实现(task_build_rootfs_img.py:980-1029):

python
class OeeBuildRootfsImg(BaseBuildRootfsImg):
    def __init__(self, config: Config, work_name=""):
        super(OeeBuildRootfsImg, self).__init__(config, work_name)
        # 社区版本适配
        if misc.community_name() != "openubmc":
            self.rootfs_img_path = f"{self.config.work_out}/rootfs_iBMC.img"
    
    def build_common_fs(self):
        """OEE模式:构建rootfs根文件系统"""
        self.chdir(self.buildimg_dir)
        self.info("开始构建 rootfs ...")
        
        # 解压OEE squashfs镜像
        oee_squashfs_path = os.path.join(self.config.sdk_path, 
            "obmc-phosphor-image-evb-ast2600-20260120133748.squashfs-xz")
        self.run_command(f"unsquashfs -f -d {self.rtos_rootfs} {oee_squashfs_path}", sudo=True)
        
        # 合并openubmc组件
        self.run_command("cp -af {}/. {}".format(self.config.rootfs_path, self.rtos_rootfs), sudo=True)
        
        # 拷贝升级dat文件
        self.copy_upgrade_dat_file()
        
        # 定制化处理
        for cus in self.customization:
            cus.rootfs_cust(self.rtos_rootfs)
        
        self.chdir(self.rtos_rootfs)
        self.strip()  # strip处理(继承)
        
        # 删除.a静态库(OEE特有)
        cmd = ["sudo find {} -type f -name *.a".format(self.rtos_rootfs), 
               "sudo xargs -P 0 -i{{}} rm {{}}"]
        self.pipe_command(cmd)
        
        self.build_cfg_fs()  # 构建cfgfs(继承)
    
    def make_rootfs_img(self):
        """OEE模式:制作rootfs镜像"""
        self.make_datafs_img()
        self.component_cust_conf()
        
        # 合并sr和soft sr,汇聚csr version
        csr_version = {}
        self.merge_sr_and_converge_version(csr_version)
        
        # 生成csr_version文件
        self.create_csr_version_file(csr_version)
        
        # 去除mds和sr文件中的空格和换行
        self.trim_mds_and_sr_json()
        
        self.component_swbom()
        self.run_command(f"sudo cp -a {self.rtos_rootfs}/. {self.mnt_datafs}/")
        self.rootfs_customization()
        
        self.chdir(self.config.work_out)
        self.create_global_properties_config_file()
        self.make_img()  # 制作镜像(继承,但不调用sign_ko)

工厂函数实现(task_build_rootfs_img.py:1031-1035):

python
def create_rootfs_builder(config: Config, work_name=""):
    """工厂函数:根据chip类型选择Rootfs构建器"""
    if config.chip == "oee":
        return OeeBuildRootfsImg(config, work_name)
    else:
        return BaseBuildRootfsImg(config, work_name)

class TaskClass(Task):
    def __init__(self, config: Config, work_name=""):
        super(TaskClass, self).__init__(config, work_name)
        self.rootfs_builder = create_rootfs_builder(config, work_name)
    
    def run(self):
        self.rootfs_builder.run()

7.5方法重写策略

表6:RTOS与OEE Rootfs构建方法对比

方法RTOS(BaseBuildRootfsImg)OEE(OeeBuildRootfsImg)
build_common_fs解压rtos.tar.gz + 合并组件 + strip解压squashfs + 合并组件 + strip + 删除.a
sign_ko签名ko模块跳过(make_img不调用)
make_rootfs_imgschema_custom + mapping_patch + precompile + sign_ko跳过schema_custom、mapping_patch、precompile

关键差异

  • RTOS:解压rtos.tar.gz,签名ko模块,执行schema_custom、mapping_patch、precompile
  • OEE:解压squashfs镜像,不签名ko,删除.a静态库,跳过RTOS特有的schema等步骤

7.6sign_ko跳过机制

在OEE模式下,sign_ko方法虽然继承但不会被调用:

BaseBuildRootfsImg.sign_ko()实现(task_build_rootfs_img.py:873-876):

python
def sign_ko(self):
    cfg = self.config.get_manufacture_config("base/signature/sign_ko", None)
    if cfg:
        self.warning("bingo工具不支持对ko文件签名,跳过此步骤!")

BaseBuildRootfsImg.make_img()调用sign_ko(task_build_rootfs_img.py:878-883):

python
def make_img(self):
    self.sign_ko()  # 调用签名ko方法
    if self.config.chip == "1711":
        self.tools.make_img(self.rootfs_img_path, self.mnt_datafs, "376")
    else:
        self.tools.make_img(self.rootfs_img_path, self.mnt_datafs, "740")

OEE模式下跳过sign_ko

  • OeeBuildRootfsImg.make_rootfs_img()直接调用make_img()
  • make_img()会调用sign_ko(),但sign_ko()在OEE下仅打印warning并跳过
  • 实际上OEE不需要签名ko模块,符合设计预期

8.配置解析模块

8.1chip类型判断逻辑

config.py实现(config.py:880-884):

python
def update_chip_info(self, platform_package):
    """根据rtos_version设置chip类型"""
    rtos_version = platform_package.get("options", {}).get("rtos_version", "rtos_v2")
    
    if rtos_version == "rtos_v2_1712":
        self.chip = "1712"
    if rtos_version == "oee":
        self.chip = "oee"
    # 默认为1711芯片(self.chip初始值)

chip类型影响

rtos_version值chip类型构建流程工厂选择
"oee""oee"OEE构建流程OeeBuildXxx子类
"rtos_v2_1712""1712"1712芯片RTOS流程BaseBuildXxx父类
"rtos_v2"或不配置"1711"(默认)1711芯片RTOS流程BaseBuildXxx父类

8.2构建流程调整

task_build_conan.py调整(task_build_conan.py):

python
def merge_dep_options(self):
    self.set_default_options()
    
    # OEE模式下跳过RTOS特有配置
    if self.config.chip != "oee":
        self.set_module_symver_options()  # 设置symver选项
        self.enable_1712_option()          # 启用1712芯片选项

task_oct_rtos.py跳过RTOS裁剪(task_oct_rtos.py):

python
def run(self):
    # OEE模式下直接返回,跳过RTOS裁剪
    if self.config.chip == "oee":
        return
    
    # RTOS裁剪流程
    self._prepare_env()
    self._download_rtos()
    self._install_rtos()
    self._merge_sdk()

task_build_linxbin.py调整(task_build_linxbin.py):

python
def run(self):
    # OEE模式下跳过灵犀核构建(如果需要)
    if self.config.chip == "oee":
        # 可能跳过或调整灵犀核构建
        pass
    
    # 灵犀核构建流程
    ...

9.RTOS与OEE差异总结

表7:RTOS与OEE构建模式差异总结

维度RTOS模式OEE模式
配置触发rtos_version非oeertos_version="oee" → chip="oee"
工具安装默认下载安装tools_install配置驱动(CustomInstaller)
BootHi1711_boot / LiteOS_Mu-boot-spl + u-boot
内核RTOS内核Linux fitImage
Rootfs来源rtos.tar.gzsquashfs-xz镜像
Boot区无独立区域mmc-bootarea.img(2MB)
GPP结构hpm_top + boot + kernel + hpm_sub + rootca + cms + crl + rootfshpm_top + mmc-bootarea + kernel + rootfs
签名签名uboot、ko不签名
工厂选择BaseBuildXxx父类OeeBuildXxx子类

10.文件变更统计

表8:文件变更统计(commit c2a6213)

文件变更行数说明
task_custom_installer.py+522行(新增)CustomInstaller基类及CustomBuildToolsInstaller/CustomSDKInstaller子类
task_buildgppbin.py+45行OeeBuildGppBin子类 + create_gpp_builder工厂函数
task_build_rootfs_img.py+74行OeeBuildRootfsImg子类 + create_rootfs_builder工厂函数
task_download_buildtools.py+23行集成CustomBuildToolsInstaller,check_custom_install_config
task_download_dependency.py+22行集成CustomSDKInstaller,check_custom_install_config
task_build_conan.py+5行OEE跳过RTOS options(chip != "oee"判断)
task_oct_rtos.py+2行OEE跳过RTOS裁剪(chip == "oee"判断)
task_build_linxbin.py+2行OEE模式调整(可能跳过灵犀核)
config.py+2行rtos_version="oee" → chip="oee"判断
manifest.schema.json+108行tools_install schema定义
bmcgo/init.py+2行版本号更新

总计:新增约805行代码,无删除原有代码,完全向后兼容。

代码质量

  • 模块化设计:每个功能独立模块,职责清晰
  • 继承架构:父类保持原有逻辑,子类仅重写必要方法
  • 工厂模式:统一接口,根据chip类型选择构建器
  • 安全机制:路径白名单、哈希验证、配置校验

11.后续扩展

11.1新芯片类型扩展

添加子类即可扩展:

BaseBuildXxx(父类)
    ├─ OeeBuildXxx(OEE子类)
    ├─ 1713BuildXxx(1713芯片子类,新增)
    └─ 其他芯片子类(新增)

扩展步骤

  1. 创建子类继承BaseBuildXxx
  2. 重写需要特化的方法
  3. 在工厂函数中添加chip类型判断
  4. 更新manifest.schema.json添加新的rtos_version枚举

11.2新安装模式扩展

扩展CustomInstaller子类:

CustomInstaller(基类)
    ├─ CustomBuildToolsInstaller
    ├─ CustomSDKInstaller
    ├─ CustomXXXInstaller(新增)
    └─ 其他安装器子类(新增)

扩展步骤

  1. 创建子类继承CustomInstaller
  2. 重写execute_specified_install方法
  3. 在对应task_xxx.py中集成新子类
  4. 更新manifest.schema.json添加新的label枚举

12.风险与规避

表9:风险分析与规避措施

风险规避措施实现位置
影响RTOS构建父类保持原有逻辑完整,工厂默认选择父类create_xxx_builder工厂函数
配置校验不全schema.json严格校验 + validate_config双重验证manifest.schema.json + task_custom_installer.py:43-82
安装冲突fcntl文件锁 + 安装缓存验证task_custom_installer.py:fcntl.lockf
路径安全sanitize_path限制安全目录白名单task_custom_installer.py:84-107
文件篡改sha256sum哈希验证,比对配置值和实际值task_custom_installer.py:109-118
缓存篡改install_flag.json权限控制,哈希比对验证task_custom_installer.py:154-169

13.测试覆盖率

表10:测试覆盖率统计

测试类型测试用例数覆盖功能点覆盖率
功能测试8配置解析、安装、GPP构建、Rootfs构建、缓存验证100%
异常测试6配置错误、路径安全、哈希验证、安装失败、缓存失效95%
性能测试3下载性能、哈希验证性能、缓存验证性能100%
安全测试5路径注入、哈希篡改、命令注入、权限提升、缓存篡改90%
总计22全流程96%

测试用例清单

  1. OEE本地模式完整构建流程
  2. OEE下载模式工具链安装
  3. 缓存验证测试(verify=true)
  4. RTOS默认模式构建(向后兼容)
  5. 1712芯片RTOS构建
  6. 配置缺失/格式错误测试
  7. 路径安全白名单测试
  8. sha256sum哈希验证测试
  9. 安装失败清理测试
  10. OEE GPP固件结构验证
  11. OEE Rootfs镜像构建验证
  12. 删除.a静态库测试
  13. 社区版本适配测试(openubmc/iBMC)
  14. 工厂函数选择测试
  15. 继承架构测试(父类/子类方法调用)
  16. 并发安装冲突测试
  17. 性能测试(下载、哈希、缓存)
  18. 安全测试(路径注入、哈希篡改)

14.总结

本特性通过配置驱动+继承架构+工厂模式实现OEE构建完整支持:

表11:设计方案总结

层次设计方案核心思想实现模块
配置层rtos_version + tools_install配置联动触发模式切换config.py
安装层CustomInstaller继承架构label驱动下载,mode驱动安装task_custom_installer.py
GPP构建层Base/Oee继承 + create_gpp_builder工厂父类RTOS,子类OEEtask_buildgppbin.py
Rootfs构建层Base/Oee继承 + create_rootfs_builder工厂父类RTOS,子类OEEtask_build_rootfs_img.py

设计优势

  1. 向后兼容:RTOS产品构建不受影响,工厂默认选择父类
  2. 配置灵活:tools_install支持local/oee/custom/default四种模式
  3. 架构清晰:继承结构职责分明,父类RTOS,子类OEE
  4. 易于扩展:新芯片/新模式只需添加子类和工厂判断
  5. 安全可靠:路径白名单、哈希验证、缓存机制、异常处理

核心创新点

  • 继承架构:父类保持原有逻辑完整,子类仅重写必要方法
  • 工厂模式:统一接口create_xxx_builder,根据chip类型选择构建器
  • 配置驱动:rtos_version决定构建模式,tools_install决定安装方式
  • 社区适配:通过misc.community_name()适配不同社区版本命名

15.参考资料清单

参考文档

  1. OEE构建模式支持设计文档:bingo/demo/oee_tools/OEE构建模式支持设计文档.md
  2. OpenEuler Embedded官方文档:https://docs.openeuler.openatom.cn/zh/
  3. bingo构建系统文档:bingo/demo/oee_tools/tools_install.md
  4. manifest.schema.json定义:bingo/tools/deb/usr/share/bingo/schema/manifest.schema.json
  5. Python hashlib官方文档:https://docs.python.org/3/library/hashlib.html
  6. JSON Schema规范:https://json-schema.org/

代码实现参考

  1. task_custom_installer.py:通用自定义安装模块(522行)
  2. task_buildgppbin.py:GPP构建模块(243行,新增45行OEE子类)
  3. task_build_rootfs_img.py:Rootfs构建模块(1044行,新增74行OEE子类)
  4. task_download_buildtools.py:构建工具下载模块(新增23行)
  5. task_download_dependency.py:SDK依赖下载模块(新增22行)
  6. config.py:配置解析模块(新增2行chip判断)
  7. task_build_conan.py:组件构建模块(新增5行OEE跳过)
  8. task_oct_rtos.py:RTOS裁剪模块(新增2行OEE跳过)

实际配置参考

  1. manifest.yml配置示例:platform/options/rtos_version、tools_install配置
  2. tools_install.md:配置文档详细说明

缩略语清单

缩略语英文全名中文解释
OEEOpenEuler EmbeddedOpenEuler嵌入式版本
SDKSoftware Development Kit软件开发工具包
RTOSReal-Time Operating System实时操作系统
HPMHost Partition Management主机分区管理升级包
GPPGeneral Purpose Package通用产品包
SHA256Secure Hash Algorithm 256-bit安全哈希算法256位
MMCMultiMediaCard多媒体卡存储接口
SPLSecondary Program Loader二级程序加载器
fitImageFlattened Image Tree扁平化镜像树格式
squashfsSquash File System压缩文件系统

表目录

表1:特性场景相关性分析 表2:特性需求列表 表3:配置示例对比 表4:OEE工具链安装与SDK依赖安装对比 表5:RTOS与OEE GPP固件结构对比 表6:RTOS与OEE Rootfs构建方法对比 表7:RTOS与OEE构建模式差异总结 表8:文件变更统计 表9:风险分析与规避措施 表10:测试覆盖率统计 表11:设计方案总结

图目录

图1:配置解析与构建模式选择流程 图2:OEE GPP构建流程 图3:OEE Rootfs构建流程